﻿#if UNITY_EDITOR
using System.Collections.Generic;
using System.IO;
using UnityEngine;
/// <summary>
/// XLSX选择资源项
/// </summary>
public class ESF_CollectAsset_XLSX : AbsESF_EditorCollectAsset
{
    /// <summary>
    /// 构造函数
    /// </summary>
    /// <param name="_pathOrGuid">资源路径或guid</param>
    public ESF_CollectAsset_XLSX(string _pathOrGuid) : base(_pathOrGuid)
    {
        isXLSX = isFile
           && enESF_UnityFileExt.Xlsx.ESF_FirstAttribute<ESF_FileExtAttribute>().IsExt(ext)
           && !name.StartsWith(@"~$");
    }

    /// <summary>
    /// 解析
    /// </summary>
    /// <param name="_index">索引</param>
    protected override void OnAfterResolve(int _index)
    {
        if (isXLSX)
        {
            xlsxAutoBuildFolderXmlConfig = ESF_Logic.xlsxAutoBuildFolder.xml;

            string className = $"Table_{nameWithoutExtension}";
            string selectMethodName = $"Select_{className}";
            string extendFileName = $"{className}_Extend";
            string helperSelectFileName = $"{className}_Select";
            xlsxTableSchemaXmlConfig = ESF_Logic.GetCacheXmlCatalog<ESF_Xml_XlsxTableSchema>(ESF_enCacheXmlCatalog.XlsxSchema, nameWithoutExtension, ESF_enCacheXmlCatalog.XlsxSchema.ToString());
            if (_index >= 0)
            {
                xlsxTableSchemaXmlConfig.xml.xlsxIndex = _index;
            }
            xlsxTableSchemaXmlConfig.xml.xlsxFilePath = path.ESF_TransPathSeparatorCharToUnityChar();
            xlsxTableSchemaXmlConfig.xml.xlsxTableClassify = ESF_Utility.GetEnumDefaultValue(xlsxTableSchemaXmlConfig.xml.xlsxTableClassify, ESF_enXlsxTableClassify.Normal);
            xlsxTableSchemaXmlConfig.SaveAsset();

            xlsxScriptBuildSettingConfig = ESF_Logic.GetCacheXmlCatalog<ESF_Xml_XlsxTable_ScriptBuildSetting>(ESF_enCacheXmlCatalog.XlsxScriptBuildSetting, nameWithoutExtension, ESF_enCacheXmlCatalog.XlsxScriptBuildSetting.ToString());
            xlsxScriptBuildSettingConfig.xml.tableIndex = xlsxTableSchemaXmlConfig.xml.xlsxIndex;
            xlsxScriptBuildSettingConfig.xml.tableName = nameWithoutExtension;
            xlsxScriptBuildSettingConfig.xml.className = className;
            xlsxScriptBuildSettingConfig.xml.helperSelectFileName = helperSelectFileName;
            xlsxScriptBuildSettingConfig.xml.selMetN = selectMethodName;
            xlsxScriptBuildSettingConfig.xml.extendFileName = extendFileName;
            xlsxScriptBuildSettingConfig.SaveAsset();

            entityBuildTextAsset = new ESF_BuildTextAsset(xlsxScriptBuildSettingConfig.xml.className,
                xlsxAutoBuildFolderXmlConfig.xlsxScriptEntityFolder, enESF_UnityFileExt.CS, string.Empty);
        }        
    }

    /// <summary>
    /// 是否是XLSX文件
    /// </summary>
    public bool isXLSX { get; private set; }
    /// <summary>
    /// Xlsx表架构Xml配置
    /// </summary>
    public ESF_BuildXmlAsset_CacheXmlCatalog<ESF_Xml_XlsxTableSchema> xlsxTableSchemaXmlConfig { get; private set; }
    /// <summary>
    /// Xlsx表自动生成目录Xml配置
    /// </summary>
    public ESF_Xml_XlsxAutoBuildFolder xlsxAutoBuildFolderXmlConfig { get; private set; }
    /// <summary>
    /// Xlsx表脚本生成设定配置
    /// </summary>
    public ESF_BuildXmlAsset_CacheXmlCatalog<ESF_Xml_XlsxTable_ScriptBuildSetting> xlsxScriptBuildSettingConfig { get; private set; }
    /// <summary>
    /// db数据库表组
    /// Key:ESF_enLanguageClassify语言类别
    /// Value:Db表资源
    /// </summary>
    public Dictionary<int, XlsxDbTable> dbTables { get; private set; }
    /// <summary>
    /// 实体脚本资源
    /// </summary>
    public ESF_BuildTextAsset entityBuildTextAsset { get; private set; }

    /// <summary>
    /// 已生成主键
    /// </summary>
    List<string> mExistKeys = new List<string>();
    /// <summary>
    /// 自动创建表资源
    /// </summary>
    public void AutoCreateTableAsset()
    {
        if (isXLSX)
        {
            ESF_BuildEngineAsset bea = new ESF_BuildEngineAsset("", "", enESF_UnityFileExt.Asset,
            typeof(XlsxDbTable).FullName);
            xlsxAutoBuildFolderXmlConfig.Resolve();
            XlsxDbTable table = null;
            dbTables = new Dictionary<int, XlsxDbTable>();
            if (xlsxAutoBuildFolderXmlConfig.langs != null)
            {
                foreach (var key in xlsxAutoBuildFolderXmlConfig.langs)
                {
                    bea.SetFileName(xlsxScriptBuildSettingConfig.xml.tableName);
                    bea.SetDirectory(key.dbTable_TargetFolder);
                    bea.LoadAsset(true);
                    table = (XlsxDbTable)bea.engineAsset;
                    table.tablePath = Path.Combine(key.xlsxTable_SrcFolder, name).ESF_TransPathSeparatorCharToUnityChar();
                    table.tableLanguage = (int)key.classify;
                    dbTables.Add((int)key.classify, table);
                }
            }
            mExistKeys.Clear();
        }        
    }

    #region CrerateNewRow 创建新行
    /// <summary>
    /// 创建新行
    /// </summary>
    /// <returns>行</returns>
    public XlsxDbTableRow CrerateNewRow()
    {
        XlsxDbTableRow row = new XlsxDbTableRow();        
        row.key = new SFSerializdata();
        row.data = new SFSerializdataOneArray();

        if (xlsxScriptBuildSettingConfig.xml.dbTypes != null)
        {
            foreach (var key in xlsxScriptBuildSettingConfig.xml.dbTypes)
            {
                switch (key.csType)
                {
                    case ESF_enCS2UnityDataType.Bool:
                        row.data.bools = OnCreateValueArray<bool>(key.dbTypeCount);
                        break;
                    case ESF_enCS2UnityDataType.Byte:
                        row.data.bytes = OnCreateValueArray<byte>(key.dbTypeCount);
                        break;
                    case ESF_enCS2UnityDataType.Char:
                        row.data.chars = OnCreateValueArray<char>(key.dbTypeCount);
                        break;
                    case ESF_enCS2UnityDataType.DateTime:
                        OnErrorSupportTip(key.csType);
                        break;
                    case ESF_enCS2UnityDataType.Decimal:
                        OnErrorSupportTip(key.csType);
                        break;
                    case ESF_enCS2UnityDataType.Double:
                        row.data.doubles = OnCreateValueArray<double>(key.dbTypeCount);
                        break;
                    case ESF_enCS2UnityDataType.Float:
                        row.data.floats = OnCreateValueArray<float>(key.dbTypeCount);
                        break;
                    case ESF_enCS2UnityDataType.Int:
                        row.data.ints = OnCreateValueArray<int>(key.dbTypeCount);
                        break;
                    case ESF_enCS2UnityDataType.Long:
                        row.data.longs = OnCreateValueArray<long>(key.dbTypeCount);
                        break;
                    case ESF_enCS2UnityDataType.SByte:
                        row.data.sbytes = OnCreateValueArray<sbyte>(key.dbTypeCount);
                        break;
                    case ESF_enCS2UnityDataType.Short:
                        row.data.shorts = OnCreateValueArray<short>(key.dbTypeCount);
                        break;
                    case ESF_enCS2UnityDataType.String:
                        row.data.strings = OnCreateValueArray<string>(key.dbTypeCount);
                        break;
                    case ESF_enCS2UnityDataType.UInt:
                        row.data.uints = OnCreateValueArray<uint>(key.dbTypeCount);
                        break;
                    case ESF_enCS2UnityDataType.ULong:
                        row.data.ulongs = OnCreateValueArray<ulong>(key.dbTypeCount);
                        break;
                    case ESF_enCS2UnityDataType.UShort:
                        row.data.ushorts = OnCreateValueArray<ushort>(key.dbTypeCount);
                        break;
                    case ESF_enCS2UnityDataType.Vector2:
                        row.data.vector2s = OnCreateValueArray<Vector2>(key.dbTypeCount);
                        break;
                    case ESF_enCS2UnityDataType.Vector3:
                        row.data.vector3s = OnCreateValueArray<Vector3>(key.dbTypeCount);
                        break;
                    case ESF_enCS2UnityDataType.Vector4:
                        row.data.vector4s = OnCreateValueArray<Vector4>(key.dbTypeCount);
                        break;
                }
            }
        }
        return row;
    }

    /// <summary>
    /// 生成值组
    /// </summary>
    /// <typeparam name="T">类型</typeparam>
    /// <param name="_length">长度</param>
    /// <returns>值组</returns>
    T[] OnCreateValueArray<T>(int _length)
    {
        return _length > 0 ? new T[_length] : default;
    }

    /// <summary>
    /// 错误提示
    /// </summary>
    /// <param name="_dataType">数据类型</param>
    void OnErrorSupportTip(ESF_enCS2UnityDataType _dataType)
    {
        ESF_P.ESF_Error($"Unity can not support 【{_dataType}】");
    }
    #endregion

    /// <summary>
    /// 设置列数据
    /// </summary>
    /// <param name="_column">列设定</param>
    /// <param name="_cellValue">列xlsx表值</param>
    /// <param name="_dbTableRow">列db行</param>
    public void SetColumnValue(ESF_Xml_XlsxTableColumn_ScriptBuildSetting _column, string _cellValue, XlsxDbTableRow _dbTableRow)
    {
        if (!string.IsNullOrEmpty(_cellValue))
        {
            switch (ESF_Logic.GetCSDataType(_column.dbType))
            {
                case ESF_enCS2UnityDataType.Bool:
                    _dbTableRow.data.bools[_column.dbOrdinal] = (bool)ResolverColumnValue(_column, _cellValue);
                    break;
                case ESF_enCS2UnityDataType.Byte:
                    _dbTableRow.data.bytes[_column.dbOrdinal] = (byte)ResolverColumnValue(_column, _cellValue);
                    break;
                case ESF_enCS2UnityDataType.Char:
                    _dbTableRow.data.chars[_column.dbOrdinal] = (char)ResolverColumnValue(_column, _cellValue);
                    break;
                case ESF_enCS2UnityDataType.DateTime:
                    OnErrorSupportTip(_column.csType);
                    break;
                case ESF_enCS2UnityDataType.Decimal:
                    OnErrorSupportTip(_column.csType);
                    break;
                case ESF_enCS2UnityDataType.Double:
                    _dbTableRow.data.doubles[_column.dbOrdinal] = (double)ResolverColumnValue(_column, _cellValue);
                    break;
                case ESF_enCS2UnityDataType.Float:
                    _dbTableRow.data.floats[_column.dbOrdinal] = (float)ResolverColumnValue(_column, _cellValue);
                    break;
                case ESF_enCS2UnityDataType.Int:
                    _dbTableRow.data.ints[_column.dbOrdinal] = (int)ResolverColumnValue(_column, _cellValue);
                    break;
                case ESF_enCS2UnityDataType.Long:
                    _dbTableRow.data.longs[_column.dbOrdinal] = (long)ResolverColumnValue(_column, _cellValue);
                    break;
                case ESF_enCS2UnityDataType.SByte:
                    _dbTableRow.data.sbytes[_column.dbOrdinal] = (sbyte)ResolverColumnValue(_column, _cellValue);
                    break;
                case ESF_enCS2UnityDataType.Short:
                    _dbTableRow.data.shorts[_column.dbOrdinal] = (short)ResolverColumnValue(_column, _cellValue);
                    break;
                case ESF_enCS2UnityDataType.String:
                    _dbTableRow.data.strings[_column.dbOrdinal] = (string)ResolverColumnValue(_column, _cellValue);
                    break;
                case ESF_enCS2UnityDataType.UInt:
                    _dbTableRow.data.uints[_column.dbOrdinal] = (uint)ResolverColumnValue(_column, _cellValue);
                    break;
                case ESF_enCS2UnityDataType.ULong:
                    _dbTableRow.data.ulongs[_column.dbOrdinal] = (ulong)ResolverColumnValue(_column, _cellValue);
                    break;
                case ESF_enCS2UnityDataType.UShort:
                    _dbTableRow.data.ushorts[_column.dbOrdinal] = (ushort)ResolverColumnValue(_column, _cellValue);
                    break;
                case ESF_enCS2UnityDataType.Vector2:
                    _dbTableRow.data.vector2s[_column.dbOrdinal] = (Vector2)ResolverColumnValue(_column, _cellValue);
                    break;
                case ESF_enCS2UnityDataType.Vector3:
                    _dbTableRow.data.vector3s[_column.dbOrdinal] = (Vector3)ResolverColumnValue(_column, _cellValue);
                    break;
                case ESF_enCS2UnityDataType.Vector4:
                    _dbTableRow.data.vector4s[_column.dbOrdinal] = (Vector4)ResolverColumnValue(_column, _cellValue);
                    break;
            }
        }
    }

    /// <summary>
    /// 是否是删除行
    /// </summary>
    /// <param name="_dbTableRow">列db行</param>
    /// <returns>true:是,false:否</returns>
    public bool IsDeleteRow(XlsxDbTableRow _dbTableRow)
    {
        bool isDel = xlsxScriptBuildSettingConfig.xml.deleteColumns != null && xlsxScriptBuildSettingConfig.xml.deleteColumns.Length > 0;
        //如果有删除判定列，则检测所有删除列是否符合条件
        if (isDel)
        {
            ESF_CSharpCodeAttribute attr = null;
            foreach (var key in xlsxScriptBuildSettingConfig.xml.deleteColumns)
            {
                attr = ESF_Logic.GetCSDataType(key.dbType).ESF_FirstAttribute<ESF_CSharpCodeAttribute>();
                switch (key.csType)
                {
                    case ESF_enCS2UnityDataType.Bool:
                        isDel &= attr.isDelete(_dbTableRow.data.bools[key.dbOrdinal]);
                        break;
                    case ESF_enCS2UnityDataType.Byte:
                        isDel &= attr.isDelete(_dbTableRow.data.bytes[key.dbOrdinal]);
                        break;
                    case ESF_enCS2UnityDataType.Char:
                        isDel &= attr.isDelete(_dbTableRow.data.chars[key.dbOrdinal]);
                        break;
                    case ESF_enCS2UnityDataType.DateTime:
                        OnErrorSupportTip(key.csType);
                        break;
                    case ESF_enCS2UnityDataType.Decimal:
                        OnErrorSupportTip(key.csType);
                        break;
                    case ESF_enCS2UnityDataType.Double:
                        isDel &= attr.isDelete(_dbTableRow.data.doubles[key.dbOrdinal]);
                        break;
                    case ESF_enCS2UnityDataType.Float:
                        isDel &= attr.isDelete(_dbTableRow.data.floats[key.dbOrdinal]);
                        break;
                    case ESF_enCS2UnityDataType.Int:
                        isDel &= attr.isDelete(_dbTableRow.data.ints[key.dbOrdinal]);
                        break;
                    case ESF_enCS2UnityDataType.Long:
                        isDel &= attr.isDelete(_dbTableRow.data.longs[key.dbOrdinal]);
                        break;
                    case ESF_enCS2UnityDataType.SByte:
                        isDel &= attr.isDelete(_dbTableRow.data.sbytes[key.dbOrdinal]);
                        break;
                    case ESF_enCS2UnityDataType.Short:
                        isDel &= attr.isDelete(_dbTableRow.data.shorts[key.dbOrdinal]);
                        break;
                    case ESF_enCS2UnityDataType.String:
                        isDel &= attr.isDelete(_dbTableRow.data.strings[key.dbOrdinal]);
                        break;
                    case ESF_enCS2UnityDataType.UInt:
                        isDel &= attr.isDelete(_dbTableRow.data.uints[key.dbOrdinal]);
                        break;
                    case ESF_enCS2UnityDataType.ULong:
                        isDel &= attr.isDelete(_dbTableRow.data.ulongs[key.dbOrdinal]);
                        break;
                    case ESF_enCS2UnityDataType.UShort:
                        isDel &= attr.isDelete(_dbTableRow.data.ushorts[key.dbOrdinal]);
                        break;
                    case ESF_enCS2UnityDataType.Vector2:
                        isDel &= attr.isDelete(_dbTableRow.data.vector2s[key.dbOrdinal]);
                        break;
                    case ESF_enCS2UnityDataType.Vector3:
                        isDel &= attr.isDelete(_dbTableRow.data.vector3s[key.dbOrdinal]);
                        break;
                    case ESF_enCS2UnityDataType.Vector4:
                        isDel &= attr.isDelete(_dbTableRow.data.vector4s[key.dbOrdinal]);
                        break;
                }
            }
        }
        if (xlsxScriptBuildSettingConfig.xml.hasPK)
        {
            foreach (var key in xlsxScriptBuildSettingConfig.xml.pkColumns)
            {//主键为空
                isDel |= ResolverColumnValue(key, _dbTableRow) == null;
            }
        }
        return isDel;
    }

    /// <summary>
    /// 解析列值
    /// </summary>
    /// <param name="_column">列</param>
    /// <param name="_value">值</param>
    /// <returns>值</returns>
    public object ResolverColumnValue(ESF_Xml_XlsxTableColumn_ScriptBuildSetting _column, object _value)
    {
        object result = default;
        string[] splitValues = null;
        string cellValue = _value == null ? string.Empty : _value.ToString();
        switch (ESF_Logic.GetCSDataType(_column.dbType))
        {
            case ESF_enCS2UnityDataType.Bool:
                bool boolValue = false;
                if (!bool.TryParse(cellValue, out boolValue))
                {
                    boolValue |= bool.TrueString.ToUpper().Equals(cellValue.ToUpper());
                    boolValue |= !(string.IsNullOrEmpty(cellValue) || cellValue.Equals("0"));//null或0 =false
                }
                result = boolValue;
                break;
            case ESF_enCS2UnityDataType.Byte:
                byte byteValue = 0;
                byte.TryParse(cellValue, out byteValue);
                result = byteValue;
                break;
            case ESF_enCS2UnityDataType.Char:
                result = string.IsNullOrEmpty(cellValue) ? char.MinValue : cellValue[0];
                break;
            case ESF_enCS2UnityDataType.DateTime:
                OnErrorSupportTip(_column.csType);
                break;
            case ESF_enCS2UnityDataType.Decimal:
                OnErrorSupportTip(_column.csType);
                break;
            case ESF_enCS2UnityDataType.Double:
                double doubleValue = 0;
                double.TryParse(cellValue, out doubleValue);
                result = doubleValue;
                break;
            case ESF_enCS2UnityDataType.Float:
                float floatValue = 0;
                float.TryParse(cellValue, out floatValue);
                result = floatValue;
                break;
            case ESF_enCS2UnityDataType.Int:
                int intValue = 0;
                int.TryParse(cellValue, out intValue);
                result = intValue;
                break;
            case ESF_enCS2UnityDataType.Long:
                long longValue = 0;
                long.TryParse(cellValue, out longValue);
                result = longValue;
                break;
            case ESF_enCS2UnityDataType.SByte:
                sbyte sbyteValue = 0;
                sbyte.TryParse(cellValue, out sbyteValue);
                result = sbyteValue;
                break;
            case ESF_enCS2UnityDataType.Short:
                short shortValue = 0;
                short.TryParse(cellValue, out shortValue);
                result = shortValue;
                break;
            case ESF_enCS2UnityDataType.String:
                result = cellValue;
                break;
            case ESF_enCS2UnityDataType.UInt:
                uint uintValue = 0;
                uint.TryParse(cellValue, out uintValue);
                result = uintValue;
                break;
            case ESF_enCS2UnityDataType.ULong:
                ulong ulongValue = 0;
                ulong.TryParse(cellValue, out ulongValue);
                result = ulongValue;
                break;
            case ESF_enCS2UnityDataType.UShort:
                ushort ushortValue = 0;
                ushort.TryParse(cellValue, out ushortValue);
                result = ushortValue;
                break;
            case ESF_enCS2UnityDataType.Vector2:
                splitValues = cellValue.ESF_Split(enESF_SeparatorSymbol.HorizontalBar | enESF_SeparatorSymbol.Underline | enESF_SeparatorSymbol.Comma);
                Vector2 v2 = Vector2.zero;
                if (splitValues.Length > 0)
                {
                    v2.x = float.Parse(splitValues[0]);
                }
                if (splitValues.Length > 1)
                {
                    v2.y = float.Parse(splitValues[1]);
                }
                result = v2;
                break;
            case ESF_enCS2UnityDataType.Vector3:
                splitValues = cellValue.ESF_Split(enESF_SeparatorSymbol.HorizontalBar | enESF_SeparatorSymbol.Underline | enESF_SeparatorSymbol.Comma);
                Vector3 v3 = Vector3.zero;
                if (splitValues.Length > 0)
                {
                    v3.x = float.Parse(splitValues[0]);
                }
                if (splitValues.Length > 1)
                {
                    v3.y = float.Parse(splitValues[1]);
                }
                if (splitValues.Length > 2)
                {
                    v3.z = float.Parse(splitValues[2]);
                }
                result = v3;
                break;
            case ESF_enCS2UnityDataType.Vector4:
                splitValues = cellValue.ESF_Split(enESF_SeparatorSymbol.HorizontalBar | enESF_SeparatorSymbol.Underline | enESF_SeparatorSymbol.Comma);
                Vector4 v4 = Vector4.zero;
                if (splitValues.Length > 0)
                {
                    v4.x = float.Parse(splitValues[0]);
                }
                if (splitValues.Length > 1)
                {
                    v4.y = float.Parse(splitValues[1]);
                }
                if (splitValues.Length > 2)
                {
                    v4.z = float.Parse(splitValues[2]);
                }
                if (splitValues.Length > 3)
                {
                    v4.w = float.Parse(splitValues[3]);
                }
                result = v4;
                break;
        }
        return result;
    }

    /// <summary>
    /// 比较列值
    /// </summary>
    /// <param name="_tableRow">数据行</param>
    /// <param name="_column">列架构</param>
    /// <param name="_value">列值</param>
    /// <returns>true:相等,false:不相等</returns>
    public bool EqualsValue(XlsxDbTableRow _tableRow, ESF_Xml_XlsxTableColumn_ScriptBuildSetting _column, object _value)
    {
        bool result = _value != null;
        if (result)
        {
            result = ResolverColumnValue(_column, _tableRow).Equals(ResolverColumnValue(_column, _value));
        }
        return result;
    }

    /// <summary>
    /// 读取列值
    /// </summary>
    /// <param name="_column">列架构</param>
    /// <param name="_tableRow">数据行</param>
    /// <returns>列值</returns>
    public object ResolverColumnValue(ESF_Xml_XlsxTableColumn_ScriptBuildSetting _column, XlsxDbTableRow _tableRow)
    {
        object result = null;
        switch (ESF_Logic.GetCSDataType(_column.dbType))
        {
            case ESF_enCS2UnityDataType.Bool:
                result = _tableRow.data.bools[_column.dbOrdinal];
                break;
            case ESF_enCS2UnityDataType.Byte:
                result = _tableRow.data.bytes[_column.dbOrdinal];
                break;
            case ESF_enCS2UnityDataType.Char:
                result = _tableRow.data.chars[_column.dbOrdinal];
                break;
            case ESF_enCS2UnityDataType.DateTime:
                OnErrorSupportTip(_column.csType);
                break;
            case ESF_enCS2UnityDataType.Decimal:
                OnErrorSupportTip(_column.csType);
                break;
            case ESF_enCS2UnityDataType.Double:
                result = _tableRow.data.doubles[_column.dbOrdinal];
                break;
            case ESF_enCS2UnityDataType.Float:
                result = _tableRow.data.floats[_column.dbOrdinal];
                break;
            case ESF_enCS2UnityDataType.Int:
                result = _tableRow.data.ints[_column.dbOrdinal];
                break;
            case ESF_enCS2UnityDataType.Long:
                result = _tableRow.data.longs[_column.dbOrdinal];
                break;
            case ESF_enCS2UnityDataType.SByte:
                result = _tableRow.data.sbytes[_column.dbOrdinal];
                break;
            case ESF_enCS2UnityDataType.Short:
                result = _tableRow.data.shorts[_column.dbOrdinal];
                break;
            case ESF_enCS2UnityDataType.String:
                result = _tableRow.data.strings[_column.dbOrdinal];
                break;
            case ESF_enCS2UnityDataType.UInt:
                result = _tableRow.data.uints[_column.dbOrdinal];
                break;
            case ESF_enCS2UnityDataType.ULong:
                result = _tableRow.data.ulongs[_column.dbOrdinal];
                break;
            case ESF_enCS2UnityDataType.UShort:
                result = _tableRow.data.ushorts[_column.dbOrdinal];
                break;
            case ESF_enCS2UnityDataType.Vector2:
                result = _tableRow.data.vector2s[_column.dbOrdinal];
                break;
            case ESF_enCS2UnityDataType.Vector3:
                result = _tableRow.data.vector3s[_column.dbOrdinal];
                break;
            case ESF_enCS2UnityDataType.Vector4:
                result = _tableRow.data.vector4s[_column.dbOrdinal];
                break;
        }
        return result;
    }

    /// <summary>
    /// 解析Key
    /// </summary>
    /// <param name="_tableRow">数据行</param>    
    public void ResolverKey(XlsxDbTableRow _tableRow)
    {
        string keyValue = string.Empty;
        List<string> pkTip = new List<string>();
        if (xlsxScriptBuildSettingConfig.xml.hasPK)
        {
            string code = File.ReadAllText(entityBuildTextAsset.filePath);
            code += File.ReadAllText(xlsxAutoBuildFolderXmlConfig.xlsxScriptHelperSizeofFilePath);
            List<object> parms = new List<object>();
            object value = null;
            foreach (var key in xlsxScriptBuildSettingConfig.xml.pkColumns)
            {
                value = ResolverColumnValue(key, _tableRow);
                parms.Add(value);
                pkTip.Add($"{key.csName}：{value.ToString()}");
            }
            object result = code.CompilerInvokeStaticMethod(xlsxScriptBuildSettingConfig.xml.className, xlsxAutoBuildFolderXmlConfig.getKeyMethodName, parms.ToArray());
            ESF_enCS2UnityDataType dbType = ESF_Logic.GetCSDataType(xlsxScriptBuildSettingConfig.xml.dbKeyType);
            switch (dbType)
            {
                case ESF_enCS2UnityDataType.Bool:
                    _tableRow.key.boolKey = (bool)result;
                    break;
                case ESF_enCS2UnityDataType.Byte:
                    _tableRow.key.byteKey = (byte)result;
                    break;
                case ESF_enCS2UnityDataType.Char:
                    _tableRow.key.charKey = (char)result;
                    break;
                case ESF_enCS2UnityDataType.DateTime:
                    OnErrorSupportTip(dbType);
                    break;
                case ESF_enCS2UnityDataType.Decimal:
                    OnErrorSupportTip(dbType);
                    break;
                case ESF_enCS2UnityDataType.Double:
                    _tableRow.key.doubleKey = (double)result;
                    break;
                case ESF_enCS2UnityDataType.Float:
                    _tableRow.key.floatKey = (float)result;
                    break;
                case ESF_enCS2UnityDataType.Int:
                    _tableRow.key.intKey = (int)result;
                    break;
                case ESF_enCS2UnityDataType.Long:
                    _tableRow.key.longKey = (long)result;
                    break;
                case ESF_enCS2UnityDataType.SByte:
                    _tableRow.key.sbyteKey = (sbyte)result;
                    break;
                case ESF_enCS2UnityDataType.Short:
                    _tableRow.key.shortKey = (short)result;
                    break;
                case ESF_enCS2UnityDataType.String:
                    _tableRow.key.stringKey = (string)result;
                    break;
                case ESF_enCS2UnityDataType.UInt:
                    _tableRow.key.uintKey = (uint)result;
                    break;
                case ESF_enCS2UnityDataType.ULong:
                    _tableRow.key.ulongKey = (ulong)result;
                    break;
                case ESF_enCS2UnityDataType.UShort:
                    _tableRow.key.ushortKey = (ushort)result;
                    break;
                case ESF_enCS2UnityDataType.Vector2:
                    _tableRow.key.vector2Key = (Vector2)result;
                    break;
                case ESF_enCS2UnityDataType.Vector3:
                    _tableRow.key.vector3Key = (Vector3)result;
                    break;
                case ESF_enCS2UnityDataType.Vector4:
                    _tableRow.key.vector4Key = (Vector4)result;
                    break;
            }
            keyValue = result.ToString();
        }
        else
        {
            _tableRow.key.ulongKey = (ulong)_tableRow.xlsxRowIndex;
            keyValue = _tableRow.noPKUniqueId.ToString();
        }

        if (!mExistKeys.Contains(keyValue))
        {
            mExistKeys.Add(keyValue);
        }
        else
        {
            ESF_P.ESF_Log($"{name} has same key=>[{keyValue}] { $"[{pkTip.ESF_Join(enESF_SeparatorSymbol.Comma)}]".ESF_ApplyStepColor()},{path}".ESF_ApplyErrorColor());
        }
    }

    /// <summary>
    /// 验证Key
    /// </summary>
    /// <returns>true:成功,false:失败</returns>
    public bool VerifyKey()
    {
        bool result = true;
        if (isXLSX)
        {
            string code = File.ReadAllText(entityBuildTextAsset.filePath);
            code += File.ReadAllText(xlsxAutoBuildFolderXmlConfig.xlsxScriptHelperSizeofFilePath);
            if (xlsxScriptBuildSettingConfig.xml.hasPK)
            {
                result = (bool)code.CompilerInvokeStaticMethod(xlsxScriptBuildSettingConfig.xml.className, xlsxAutoBuildFolderXmlConfig.verifyKeyMethodName, null);
                if (!result)
                {
                    List<string> tip = new List<string>();
                    foreach (var key in xlsxScriptBuildSettingConfig.xml.pkColumns)
                    {
                        tip.Add($"{key.csName}_sizeof({key.sizeofType})");
                    }
                    ESF_P.ESF_Error($"{path} pk column [{$"{tip.ESF_Join(enESF_SeparatorSymbol.Plus)} > sizeof({ESF_enCS2UnityDataType.ULong.ESF_FirstAttribute<ESF_CSharpCodeAttribute>().unityType})".ESF_ApplyStepColor()}]");
                }
            }
        }        
        return result;
    }
}
#endif
